#include <fstream>
#include <string>

struct node;
class aut;
class aut_checker;

struct node
{
    node * * next;
    bool term;
    unsigned number;
    node();
    ~node();
};

class aut
{
    node * nodes_;
    unsigned n_, m_, alph_size_;
    char f_, l_;
    unsigned get_char_n_(char c);
public:
    friend std::ifstream& operator>> (std::ifstream&, aut&);
    aut(char, char);
    friend class aut_checker;
    ~aut();
};

class aut_checker
{
    aut * first_, * second_;
    char f_, l_;
    unsigned alph_size_;
    bool dfs_(node *, node *, bool *, bool *);
public:
    friend std::ifstream& operator>> (std::ifstream&, aut_checker&);
    std::string result();
    aut_checker(char, char);
    ~aut_checker();
};

node::node():
term(false), next(0), number(0)
{

}

node::~node()
{
    if (next)
    {
        delete[] next;
    }
}

aut::aut(char f, char l):
f_(f), l_(l), alph_size_(l - f + 1)
{

}

aut::~aut()
{
    delete[] nodes_;
}

std::ifstream& operator>>(std::ifstream& in, aut& at)
{
    unsigned n, m, k;
    in >> n >> m >> k;
    at.n_ = n + 1;
    at.m_ = m;
    if (!at.nodes_)
        delete[] at.nodes_;
    at.nodes_ = new node[n + 1];
    unsigned a, b;
    char c;
    for (unsigned i = 0; i <= n; ++i)
    {
        at.nodes_[i].number = i;
        at.nodes_[i].next = new node*[at.alph_size_];
        memset(at.nodes_[i].next, 0, sizeof(node *) * at.alph_size_);
    }
    for (unsigned i = 0; i < k; ++i)
    {
        in >> a;
        at.nodes_[a].term = true;
    }
    for (unsigned i = 0; i < m; ++i)
    {
        in >> a >> b >> c;
        at.nodes_[a].next[at.get_char_n_(c)] = at.nodes_ + b;
    }
    return in;
}

unsigned aut::get_char_n_(char c)
{
    return c - f_;
}

aut_checker::~aut_checker()
{
    if (first_)
    {
        delete first_;
    }
    if (second_)
    {
        delete second_;
    }
}

aut_checker::aut_checker(char first, char last):
f_(first), l_(last), alph_size_(l_ - f_ + 1)
{
    first_ = new aut(f_, l_);
    second_ = new aut(f_, l_);
}

std::ifstream& operator>> (std::ifstream& in, aut_checker& a)
{
    in >> (*a.first_) >> (*a.second_);
    return in;
}

std::string aut_checker::result()
{
    bool * vf = new bool[first_->n_], * vs = new bool[second_->n_];
    memset(vf, 0, sizeof(bool) * (first_->n_));
    memset(vs, 0, sizeof(bool) * (second_->n_));
    node * curf = first_->nodes_ + 1, * curs = second_->nodes_ + 1;
    std::string ans;
    if (dfs_(curf, curs, vf, vs))
    {        
        ans = std::string("YES");
    }
    else
    {
        ans = std::string("NO");
    }
    delete[] vf;
    delete[] vs;
    return ans;
}

bool aut_checker::dfs_(node * curf, node * curs, bool * vf, bool * vs)
{
    vf[curf->number] = true;
    vs[curs->number] = true;
    for (unsigned i = 0; i < alph_size_; ++i)
    {
        if (curf->next[i] != 0 && !vf[curf->next[i]->number])
        {
            if ((curs->next[i] == 0) || vs[curs->next[i]->number] || !dfs_(curf->next[i], curs->next[i], vf, vs))
            {
                return false;
            }
        }
        else
        {
            if (curs->next[i] != 0 && curf->next[i] == 0)
            {
                return false;
            }
        }
    }
    if (curf->term != curs->term)
        return false;
    else
        return true;
}

int main()
{
    std::ifstream in("isomorphism.in");
    std::ofstream out("isomorphism.out");
    aut_checker a('a', 'z');
    in >> a;
    out << a.result();
    return 0;
}